#include "ninesquaregrid.h"
#include "sudokucell.h"
#include <QPainter>
#include "sudokucellsignals.h"
#include <QPainter>

namespace sudoku_ui {


    QColor NineSquareGrid::g_lineColor = QColor::fromRgb(112, 128, 144);
    float NineSquareGrid::g_lineWidth = 1.f;

    NineSquareGrid::NineSquareGrid(QWidget *parent)
        : QWidget{parent}
    {
        for (auto i = 1; i <= 9; i++)
        {
            this->m_cells.insert(std::make_pair(i, new SudokuCell(i, this)));

            connect(SudokuCellSignals::globalInstance(),
                    &SudokuCellSignals::selectedCell,
                    this,
                    &NineSquareGrid::onSelectedCell);
        }
    }

    NineSquareGrid::NineSquareGrid(int index, QWidget *parent)
        : QWidget{parent}
        , m_index(index)
    {
        for (auto i = 1; i <= 9; i++)
        {
            this->m_cells.insert(std::make_pair(i, new SudokuCell(i, this)));

            connect(SudokuCellSignals::globalInstance(),
                    &SudokuCellSignals::selectedCell,
                    this,
                    &NineSquareGrid::onSelectedCell);
        }
    }

    NineSquareGrid::~NineSquareGrid()
    {
        for (auto & cell : this->m_cells)
        {
            cell.second->deleteLater();
        }
        this->m_cells.clear();
    }

    void NineSquareGrid::setValue(int index, int value)
    {
        if (index < 0 || index > 8)
            return;
        this->m_cells[index + 1]->setValue(value);
    }

    void NineSquareGrid::setHintValue(int index, int value)
    {
        if (index < 1 || index > 9)
            return;
        this->m_cells[index]->updateValue(value);
    }

    int NineSquareGrid::value(int index)
    {
        if (index < 1 || index > 9 || this->m_cells.count(index) == 0)
            return 0;
        return this->m_cells[index]->value();
    }

    SudokuCell *NineSquareGrid::cell(int index)
    {
        if (index < 1 || index > 9 || this->m_cells.count(index) == 0)
            return nullptr;

        return this->m_cells[index];
    }

    void NineSquareGrid::newGame()
    {
        for (auto& cell : this->m_cells)
        {
            cell.second->setValue();
            cell.second->setSame();
            cell.second->unSelect();
        }
    }

    int NineSquareGrid::index() const
    {
        return this->m_index;
    }

    void NineSquareGrid::globalSetLineColor(const QColor &color)
    {
        if (NineSquareGrid::g_lineColor != color)
        {
            NineSquareGrid::g_lineColor = color;
        }
    }

    const QColor &NineSquareGrid::globalGetLineColor()
    {
        return NineSquareGrid::g_lineColor;
    }

    void NineSquareGrid::globalSetLineWidth(float linewidth)
    {
        if (NineSquareGrid::g_lineWidth != linewidth)
            NineSquareGrid::g_lineWidth = linewidth;
    }

    float NineSquareGrid::globalLineWidth()
    {
        return NineSquareGrid::g_lineWidth;
    }

    void NineSquareGrid::onSelectedCell(SudokuCell *cell)
    {
        auto selected = false;
        for (const auto& thisCell : this->m_cells)
        {
            if (thisCell.second != cell)
                thisCell.second->unSelect();
            else
            {
                this->m_selectCell = cell;
                selected = true;
            }
        }
        if (!selected)
            this->m_selectCell = nullptr;
        else
            SudokuCellSignals::selectedNineSquareGrid(this);
    }

    void NineSquareGrid::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event)
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(NineSquareGrid::g_lineColor, NineSquareGrid::g_lineWidth));
        auto w = this->width() / 3.f;
        auto h = this->height() / 3.f;

        float x2 = this->width();
        float y2 = this->height();
        for (auto i = 0; i <= 3; i++)
        {
            auto x = w * i;
            auto y = h * i;
            painter.drawLine(QPointF(x, 0.f), QPointF(x, y2));
            painter.drawLine(QPointF(0, y), QPointF(x2, y));
        }
    }

    void NineSquareGrid::resizeEvent(QResizeEvent *event)
    {
        Q_UNUSED(event)
        auto w = this->width() / 3.f - NineSquareGrid::g_lineWidth;
        auto h = this->height() / 3.f - NineSquareGrid::g_lineWidth;

        for (auto i = 1; i <= 9; i++)
        {
            auto m = (i - 1) % 3;
            auto n = (i - 1) / 3;
            auto x = m * (w + NineSquareGrid::g_lineWidth);
            auto y = n * (h + NineSquareGrid::g_lineWidth);
            this->m_cells[i]->setGeometry(QRectF(x + NineSquareGrid::g_lineWidth * 0.5f, y + NineSquareGrid::g_lineWidth * 0.5f, w, h).toRect());
        }
    }



}


